23. Exercise: Add CountDownTimer

L5 38 Add The Timer SC

Now it’s your turn to complete this exercise yourself.

Let's add the CountDownTimer.

1. Copy the provided companion object with the timer constants:

In GameViewModel, copy the following companion object code. This companion object has constants for our timer:

companion object {
    // These represent different important times
    // This is when the game is over
    const val DONE = 0L
    // This is the number of milliseconds in a second
    const val ONE_SECOND = 1000L
    // This is the total time of the game
    const val COUNTDOWN_TIME = 60000L
}

Feel free to change the COUNTDOWN_TIME constant so that the game doesn't last a whole minute. This can be helpful for running the app to check whether it's working.

2. Create a timer field of type CountDownTimer in the GameViewModel:
You don’t need to worry about initializing it yet. Just declare it and ignore the error for now.

3. Create a properly encapsulated LiveData for the current time called currentTime:

Use the same method as you did earlier to encapsulate LiveData for score and word. The type of currentTime should be of type Long.

4. Copy over the CountDownTimer code and then update currentTime and eventGameFinish appropriately as the timer ticks and finishes:

In the init of GameViewModel, copy the CountDownTimer code below:

timer = object : CountDownTimer(COUNTDOWN_TIME, ONE_SECOND) {

    override fun onTick(millisUntilFinished: Long) {
        // TODO implement what should happen each tick of the timer
    }

    override fun onFinish() {
        // TODO implement what should happen when the timer finishes
    }
}

timer.start()

What should happen on each tick? What about when the timer finishes? Fill these in yourself.

5. Update the logic in the nextWord function so that it doesn't end the game:

The game should finish when the timer runs out not when there are no words left in the list. If there are no words in the list, you should add the words back to the list and re-shuffle the list.

You can do this using resetList. Update the code so that it doesn't end the game, but instead calls resetList.

6. Cancel the timer in onCleared:

To avoid memory leaks, you should always cancel a CountDownTimer if you no longer need it. To do that, you can call:

override fun onCleared() {
    super.onCleared()
    timer.cancel()
}

7. Update the UI:

You want the timerText on screen to show the appropriate time. Figure out how to use LiveData from the GameViewModel to do this - remember, you've done something similar for score and word. You'll need to convert the Long for the timer into a String. You can use the DateUtils tool to do that:

DateUtils.formatElapsedTime(newTime)

Run the code to see your new timer working.

If you want to start at this step, you can download this exercise code from: Step.06-Exercise-Add-the-Timer.

You will find plenty of //TODO comments to help you complete this exercise, and if you get stuck, go back and watch the video again.

Once you’re done, you can check your solution against the solution we’ve provided here Step.06-Solution-Add-the-Timer or using this git diff.

Task Description:

Check the steps below as you implement them to complete this exercise.

Task List:

Task Feedback:

Delightful! You have a timer! You can check your solution against the solution we’ve provided here Step.06-Solution-Add-the-Timer or using this git diff.

Reference documentation